package com.rx.mylist.service;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.alibaba.fastjson.JSON;
import com.rx.core.base.RxBaseConstant;
import com.rx.core.base.RxBaseData;
import com.rx.core.base.RxResponse;
import com.rx.core.dbase.RxMarkDbMust;
import com.rx.core.enm.HANDLER_TYPE;
import com.rx.core.enm.RESULT_CODE;
import com.rx.core.enm.RX_STATUS;
import com.rx.core.iface.RelationQuery;
import com.rx.core.service.RxBaseAbstractService;
import com.rx.core.service.StandardService;
import com.rx.core.util.EmptyChecker;
import com.rx.core.util.RxUtil;
import com.rx.mylist.bean.*;
import com.rx.mylist.dao.ListCompanyInfoMapper;
import com.rx.mylist.vo.*;
import com.rx.mylist.vo.relation.DoubleListCompanyInfo;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ListService extends ListBothService {


    @Autowired
    ListCompanyInfoMapper listCompanyInfoMapper;

    private ListAccountInfo getAccountInfo(String openId){

        try {
            ListAccountInfo mineAccuScores = (ListAccountInfo) ListAccountInfo.create(ListAccountInfo.class, HANDLER_TYPE.SINGLE_LIST);
            mineAccuScores.setOtherBid(openId);
            mineAccuScores.getHandlerController().onlyDefault();
            Object object = standardService.searchList(mineAccuScores);

            List<ListAccountInfo> list = RxUtil.result(object);
            if(EmptyChecker.notEmpty(list)){
                return list.get(0);
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }

        return null;
    }

    private ListAccountInfo saveAccountInfo(ListLoginVo appLoginVo) throws IllegalAccessException, InstantiationException {

        ListAccountInfo mineAccuScores = (ListAccountInfo) ListAccountInfo.create(ListAccountInfo.class, HANDLER_TYPE.SINGLE_INSERT);
        mineAccuScores.setOtherBid(appLoginVo.getOpenId());
        mineAccuScores.setNickName(appLoginVo.getNickName());
        mineAccuScores.setRealName(appLoginVo.getRealName());
        mineAccuScores.setPhone(appLoginVo.getPhone());
        mineAccuScores.setPoint(0);
        mineAccuScores.setLevel(0);
        mineAccuScores.setSignInRecord(0);
        mineAccuScores.setStatus(RX_STATUS.NORMAL.getCode());
        mineAccuScores.getHandlerController().onlyDefault();
        Object object = standardService.insert(mineAccuScores);
        return mineAccuScores;
    }


    private Object wxLogin(ListLoginVo appLoginVo){
        WxMaService wxMaService = ((WxMaService) wxConfiguration.wxService(wxConfiguration.wxMaConfig()));
        try {
            WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(appLoginVo.getCode());
            //appLoginVo.setAccessToken(wxMaService.getAccessToken());
            // 根据session 查询是否用户是否注册，
            ListAccountInfo mineAccuScores = getAccountInfo(appLoginVo.getLoginType() + session.getOpenid());
            if(EmptyChecker.notEmpty(mineAccuScores)) {
                RxUtil.CheckUtil.check(!RX_STATUS.NORMAL.getCode().equalsIgnoreCase(mineAccuScores.getStatus()), RESULT_CODE.MESSAGE, "账号异常");

                //生成token 给前端。
                String uuid = RxUtil.getGUID();
                appLoginVo.setToken(uuid);
                appLoginVo.setPoint(mineAccuScores.getPoint());
                appLoginVo.setSignInRecord(mineAccuScores.getSignInRecord());
                appLoginVo.setLastSignDate(mineAccuScores.getLastSignDate());
                appLoginVo.setOpenId(session.getOpenid());
                appLoginVo.setLevel(mineAccuScores.getLevel());
                appLoginVo.setBid(mineAccuScores.getBid());
                appLoginVo.setVer(mineAccuScores.getVer());
                appLoginVo.setSessionKey(session.getSessionKey());

                if(appLoginVo.getNickName().indexOf("微信用户") == 0){
                    appLoginVo.setNickName(mineAccuScores.getNickName());
                }

                boolean needChange = false;

                if(!mineAccuScores.getNickName().equalsIgnoreCase(appLoginVo.getNickName())){
                    mineAccuScores.setNickName(appLoginVo.getNickName());
                    needChange = true;
                }
                if(EmptyChecker.isEmpty(mineAccuScores.getRealName())&&EmptyChecker.notEmpty(appLoginVo.getRealName())){
                    mineAccuScores.setRealName(appLoginVo.getRealName());
                    needChange = true;
                }else{
                    appLoginVo.setRealName(mineAccuScores.getRealName());
                }
                if(EmptyChecker.isEmpty(mineAccuScores.getPhone())&&EmptyChecker.notEmpty(appLoginVo.getPhone())){
                    mineAccuScores.setPhone(appLoginVo.getPhone());
                    needChange = true;
                }else{
                    appLoginVo.setPhone(mineAccuScores.getPhone());
                }

                if(needChange){
                    mineAccuScores.resetHandlerType(HANDLER_TYPE.SINGLE_UPDATE);
                    mineAccuScores.getHandlerController().onlyDefault();
                    standardService.update(mineAccuScores);
                    appLoginVo.setVer(appLoginVo.getVer()+1);
                }

                cacheService.putData(uuid,appLoginVo);
                cacheService.putData(session.getOpenid(),uuid);
            }else {
                // 首次登录
                appLoginVo.setOpenId(appLoginVo.getLoginType() + session.getOpenid());
                mineAccuScores = saveAccountInfo(appLoginVo);
                String uuid = RxUtil.getGUID();
                appLoginVo.setToken(uuid);
                appLoginVo.setSessionKey(session.getSessionKey());
                appLoginVo.setPoint(0);
                appLoginVo.setSignInRecord(0);
                appLoginVo.setOpenId(session.getOpenid());
                appLoginVo.setLevel(0);
                appLoginVo.setBid(mineAccuScores.getBid());
                appLoginVo.setVer(mineAccuScores.getVer());
                cacheService.putData(uuid,appLoginVo);
                cacheService.putData(session.getOpenid(),uuid);
            }

            return appLoginVo;

        } catch (WxErrorException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
        return null;
    }
    @Transactional
    public Object appLogin(ListLoginVo appLoginVo) throws IllegalAccessException, InstantiationException {

        RxUtil.CheckUtil.check(appLoginVo.getLoginType(), RESULT_CODE.MESSAGE,"登录类型为空");

        RxUtil.CheckUtil.condition(EmptyChecker.isEmpty(appLoginVo.getCode())&&EmptyChecker.isEmpty(appLoginVo.getToken()), RESULT_CODE.MESSAGE,"登录Code为空");


        if(EmptyChecker.notEmpty(appLoginVo.getToken())||EmptyChecker.notEmpty(appLoginVo.getOpenId())){

            // 判断是否登录。TODO:以后换分布式缓存
            String token = appLoginVo.getToken();
            if(EmptyChecker.isEmpty(token)){
                token = (String)cacheService.getData(appLoginVo.getOpenId());
                if(EmptyChecker.isEmpty(token)){
                    RxUtil.CheckUtil.throwOut(RESULT_CODE.LOGIN_ERR,"未登录");
                }
            }
            ListLoginVo appLogin = (ListLoginVo)cacheService.getData(token);
            if(EmptyChecker.isEmpty(appLogin)){
                RxUtil.CheckUtil.throwOut(RESULT_CODE.LOGIN_ERR,"未登录");
            }

            if(appLoginVo.getNickName().indexOf("微信用户") == 0){
                appLoginVo.setNickName(appLogin.getNickName());
            }
            boolean needChanage = false;

            ListAccountInfo mineAccuScores = (ListAccountInfo)ListAccountInfo.create(ListAccountInfo.class,HANDLER_TYPE.SINGLE_UPDATE);
            if(EmptyChecker.isEmpty(appLogin.getRealName())&&EmptyChecker.notEmpty(appLoginVo.getRealName())){
                mineAccuScores.setRealName(appLoginVo.getRealName());
                needChanage = true;
            }
            if(EmptyChecker.isEmpty(appLogin.getPhone())&&EmptyChecker.notEmpty(appLoginVo.getPhone())){
                mineAccuScores.setPhone(appLoginVo.getPhone());
                needChanage = true;
            }
            if(!appLogin.getNickName().equalsIgnoreCase(appLoginVo.getNickName())){
                mineAccuScores.setNickName(appLoginVo.getNickName());
                needChanage = true;

            }

            if(needChanage){
                mineAccuScores.resetHandlerType(HANDLER_TYPE.SINGLE_UPDATE);
                mineAccuScores.getHandlerController().onlyDefault();
                mineAccuScores.setBid(appLogin.getBid());
                mineAccuScores.setVer(appLogin.getVer());
                standardService.update(mineAccuScores);


                appLogin.setVer(appLogin.getVer()+1);
                appLogin.setNickName(appLoginVo.getNickName());
                cacheService.putData(token,appLogin);
            }
            return appLogin;

        }

        if(WX.equalsIgnoreCase(appLoginVo.getLoginType())){
            return wxLogin(appLoginVo);
        }
        RxUtil.CheckUtil.throwOut(RESULT_CODE.FAIL,"登录失败");
        return "";

    }

    @Transactional
    public Object updateUser(ListLoginVo appLoginVo) throws IllegalAccessException, InstantiationException {
        RxUtil.CheckUtil.check(appLoginVo.getToken(), RESULT_CODE.MESSAGE,"未登录");
// 判断是否登录。TODO:以后换分布式缓存
        ListLoginVo appLogin = (ListLoginVo)cacheService.getData(appLoginVo.getToken());
        if(EmptyChecker.isEmpty(appLogin)){
            RxUtil.CheckUtil.throwOut(RESULT_CODE.LOGIN_ERR,"未登录");
        }

        ListAccountInfo mineAccuScores = (ListAccountInfo) ListAccountInfo.create(ListAccountInfo.class, HANDLER_TYPE.SINGLE_UPDATE);
        mineAccuScores.setBid(appLogin.getBid());
        mineAccuScores.setVer(appLogin.getVer());
        mineAccuScores.setRealName(appLoginVo.getRealName());
        mineAccuScores.setPhone(appLoginVo.getPhone());
        mineAccuScores.setNickName(appLoginVo.getNickName());
        mineAccuScores.getHandlerController().onlyDefault();
        Object object = standardService.update(mineAccuScores);

        appLogin.setVer(appLogin.getVer() + 1);
        appLogin.setRealName(appLoginVo.getRealName());
        appLogin.setPhone(appLoginVo.getPhone());
        appLogin.setNickName(appLoginVo.getNickName());
        cacheService.putData(appLogin.getToken(),appLogin);
        return mineAccuScores;
    }
        private Integer getScoreBySign(int signFlg){
        signFlg++;
        signFlg = signFlg - (signFlg & (signFlg - 1));

        switch(signFlg){
            case 0:
            case 1:
                return 0;
            case 2:
                return 1;
            case 4:
                return 2;
            case 8:
                return 3;
            case 16:
                return 4;
            case 32:
                return 5;

        }
        return 5;
    }
    public static int differentDaysByMillisecond(Date date1,Date date2){

        if(EmptyChecker.isEmpty(date1)){
            //10天代表不连续
            return 10;
        }

        Calendar calendarNow = Calendar.getInstance();
        calendarNow.setTime(date1);

        Calendar calendar= Calendar.getInstance();
        calendar.set(calendarNow.get(Calendar.YEAR),
                calendarNow.get(Calendar.MONTH),
                calendarNow.get(Calendar.DATE),0,0,0);
        //年月日 也可以具体到时分秒如calendar.set(2015, 10, 12,11,32,52);
        Date tmp=calendar.getTime();//date就是你需要的时间


        int days = (int) ((date2.getTime() - tmp.getTime()) / (1000*3600*24));
        return days;
    }
    @Transactional
    public Object sign(ListLoginVo appLoginVo) throws IllegalAccessException, InstantiationException {
        RxUtil.CheckUtil.check(appLoginVo.getToken(), RESULT_CODE.MESSAGE,"未登录");
        // 判断是否登录。TODO:以后换分布式缓存
        ListLoginVo appLogin = (ListLoginVo)cacheService.getData(appLoginVo.getToken());
        if(EmptyChecker.isEmpty(appLogin)){
            RxUtil.CheckUtil.throwOut(RESULT_CODE.LOGIN_ERR,"未登录");
        }

        ListAccountInfo mineAccuScores = (ListAccountInfo) ListAccountInfo.create(ListAccountInfo.class, HANDLER_TYPE.SINGLE_UPDATE);
        mineAccuScores.setBid(appLogin.getBid());
        mineAccuScores.setVer(appLogin.getVer());

        int signFlg = appLogin.getSignInRecord() == null?0:appLogin.getSignInRecord();

        int diff = differentDaysByMillisecond(appLogin.getLastSignDate(),appLogin.getCurrentDate());

        signFlg = signFlg << diff;
        signFlg++;
        signFlg= signFlg&8191; // 去掉高位。


        mineAccuScores.setSignInRecord(signFlg);
        mineAccuScores.setLastSignDate(new Date());
        mineAccuScores.setPoint(appLogin.getPoint()== null?0:appLogin.getPoint() + getScoreBySign(signFlg));
        mineAccuScores.setLevel(appLogin.getLevel());
        if(mineAccuScores.getPoint() > 50){
            appLogin.setLevel(2);
        }

        mineAccuScores.getHandlerController().onlyDefault();
        Object object = standardService.update(mineAccuScores);

        appLogin.setVer(appLogin.getVer() + 1);
        appLogin.setSignInRecord(signFlg);
        appLogin.setLastSignDate(new Date());
        appLogin.setPoint(mineAccuScores.getPoint());
        cacheService.putData(appLogin.getToken(),appLogin);
        return mineAccuScores;

    }



    public Object listSquare(ListLoginVo appLoginVo) throws IllegalAccessException, InstantiationException {


        DoubleListCompanyInfo condition = (DoubleListCompanyInfo) RxBaseData.create(DoubleListCompanyInfo.class, ListProductInfo.class,HANDLER_TYPE.DOUBLE_LEFT_LIST);
        condition.setShowSquare(SHOW_SQUARE);
        ((ListProductInfo) ((RelationQuery) condition).obtainRelation()).setShowSquare(SHOW_SQUARE);
        ((ListProductInfo) ((RelationQuery) condition).obtainRelation()).setStatus(RX_STATUS.NORMAL.getCode());
        condition.setStatus(RX_STATUS.NORMAL.getCode());
        condition.setCity(appLoginVo.getCity());
        condition.setListCode(appLoginVo.getListCode());
        condition.setBid(appLoginVo.getBid());
        condition.getHandlerController().onlyDefault();

        Object object =  standardService.leftSearchList(condition);

        List<RxMarkDbMust> resultList =  RxUtil.assToTree(RxUtil.result(object));
        for (RxMarkDbMust rxMarkDbMust : resultList) {
            DoubleListCompanyInfo info = (DoubleListCompanyInfo)rxMarkDbMust;
            if(EmptyChecker.notEmpty(info.getDataList())){
                info.setProducts(info.getDataList());
            }else {
                info.setProducts(null);
            }
            info.setDataList(null);
        }
        return resultList;
    }

    private void setConditionForCompany(ListCompanyInfo condition,ListSearchVo appLoginVo){
        condition.setStatus(RX_STATUS.NORMAL.getCode());
        condition.getHandlerController().onlyDefault();
        condition.setPageNum(appLoginVo.getPageNum()==null?1:appLoginVo.getPageNum());
        condition.setPageSize(appLoginVo.getPageSize()==null?10:appLoginVo.getPageSize());
        Map<String,Object> map = condition.conditionMap();
        map.put("inType",Arrays.asList("00",appLoginVo.getType()));
        map.put("inCity",Arrays.asList("置顶",appLoginVo.getCity()));
        condition.setListCode(appLoginVo.getListCode());

    }

    private Map<String,List<ListProductInfo>> getProductMap(List<String> bidList) throws IllegalAccessException, InstantiationException {
        ListProductInfo productInfo = (ListProductInfo)RxBaseData.create(ListProductInfo.class,HANDLER_TYPE.SINGLE_LIST);

        productInfo.setStatus(RX_STATUS.NORMAL.getCode());
        productInfo.setShowSquare(SHOW_SQUARE);


        Map<String,Object> map = new HashMap<>();
        map.put("inCompanyBid",bidList);
        productInfo.setCondition(map);


        Object prod =  standardService.searchList(productInfo);

        List<ListProductInfo> productInfoList =  RxUtil.result(prod);

        Map<String,List<ListProductInfo>> mapProd = productInfoList.stream().collect(Collectors.groupingBy(ListProductInfo::getCompanyBid));
        return mapProd;
    }

    private void setResultList(ListCompanyInfo listCompanyInfo, List<DoubleListCompanyInfo> resultList,Map<String,List<ListProductInfo>> mapProd){

        DoubleListCompanyInfo info = new DoubleListCompanyInfo();
        RxUtil.copyProperties(listCompanyInfo,info);

        List<ListProductInfo> prodList = mapProd.get(info.getBid());
        if(EmptyChecker.notEmpty(prodList)){

            List<RxBaseData> rxBaseDataList = new ArrayList<>();
            for (ListProductInfo listProductInfo : prodList) {
                listProductInfo.appendFilter(Arrays.asList(
                        RxUtil.StringUtil.lineToHump(ListProductInfo.UPDATE_DATE),
                        RxUtil.StringUtil.lineToHump(ListProductInfo.VER),
                        RxUtil.StringUtil.lineToHump(ListProductInfo.VALID),
                        RxUtil.StringUtil.lineToHump("STATUS"),
                        RxUtil.StringUtil.lineToHump(ListProductInfo.AD_WORD.toLowerCase()),
                        RxUtil.StringUtil.lineToHump(ListProductInfo.COMPANY_BID.toLowerCase())));
                rxBaseDataList.add(listProductInfo);
            }
            info.setProducts(rxBaseDataList);
        }
        info.appendFilter(
                Arrays.asList(
                        RxUtil.StringUtil.lineToHump(ListProductInfo.VER),
                        RxUtil.StringUtil.lineToHump(ListProductInfo.VALID),
                        RxUtil.StringUtil.lineToHump("CITY"),
                        RxUtil.StringUtil.lineToHump(ListCompanyInfo.UPDATE_DATE)));
        resultList.add(info);
    }

    public Object listSquarePage(ListSearchVo appLoginVo) throws IllegalAccessException, InstantiationException {


        List<DoubleListCompanyInfo> resultList =  new ArrayList<>();
        if(EmptyChecker.isEmpty(appLoginVo.getSuggest())){
            ListCompanyInfo condition = (ListCompanyInfo) RxBaseData.create(ListCompanyInfo.class, HANDLER_TYPE.SINGLE_PAGE);
            setConditionForCompany(condition,appLoginVo);
            Object object =  standardService.searchPage(condition);
            List<ListCompanyInfo> list = RxUtil.result(object);

            if(EmptyChecker.isEmpty(list)){
                return list;
            }

            List<String> bidList = list.stream().map(e->e.getBid()).collect(Collectors.toList());

            Map<String,List<ListProductInfo>> mapProd  = getProductMap(bidList);

            for (ListCompanyInfo listCompanyInfo : list) {
                setResultList(listCompanyInfo,resultList,mapProd);
            }

        }else {
            DoubleListCompanyInfo condition = (DoubleListCompanyInfo) RxBaseData.create(DoubleListCompanyInfo.class,ListRelCompany.class, HANDLER_TYPE.DOUBLE_PAGE);
            setConditionForCompany(condition,appLoginVo);

            ((ListRelCompany) ((RelationQuery) condition).obtainRelation()).setSuggest(appLoginVo.getSuggest());
            ((ListRelCompany) ((RelationQuery) condition).obtainRelation()).setStatus(RX_STATUS.NORMAL.getCode());
            ((ListRelCompany) ((RelationQuery) condition).obtainRelation()).setReturnType(ListRelCompany.ASS_CODE);

            Object object =  standardService.innerSearchPage(condition);
            List<DoubleListCompanyInfo> list = RxUtil.result(object);

            if(EmptyChecker.isEmpty(list)){
                return list;
            }

            List<String> bidList = list.stream().map(e->e.getBid()).collect(Collectors.toList());

            Map<String,List<ListProductInfo>> mapProd  = getProductMap(bidList);

            for (ListCompanyInfo listCompanyInfo : list) {
                setResultList(listCompanyInfo,resultList,mapProd);
            }
        }



        return resultList;
    }

    public Object listProductPage(ListSearchVo appLoginVo) throws IllegalAccessException, InstantiationException {

        RxUtil.CheckUtil.check(appLoginVo.getTitle(), RESULT_CODE.MESSAGE,"没有TITLE");
        RxUtil.CheckUtil.check(appLoginVo.getCompanyBid(), RESULT_CODE.MESSAGE,"没有公司");

        ListProductInfo condition = (ListProductInfo) RxBaseData.create(ListProductInfo.class, HANDLER_TYPE.SINGLE_PAGE);

        condition.setStatus(RX_STATUS.NORMAL.getCode());
        condition.getHandlerController().onlyDefault();
        condition.setPageNum(appLoginVo.getPageNum()==null?1:appLoginVo.getPageNum());
        condition.setPageSize(appLoginVo.getPageSize()==null?10:appLoginVo.getPageSize());
        condition.setCode(appLoginVo.getCode());
        condition.setTitle(appLoginVo.getTitle());
        condition.setCompanyBid(appLoginVo.getCompanyBid());

        Object object =  standardService.searchPage(condition);

        List<ListProductInfo> resultList =  RxUtil.result(object);
        for (ListProductInfo uuaUserInfo : resultList) {
            uuaUserInfo.appendFilter(
                    Arrays.asList(
                            RxUtil.StringUtil.lineToHump(ListProductInfo.UPDATE_DATE),
                            RxUtil.StringUtil.lineToHump(ListProductInfo.VER),
                            RxUtil.StringUtil.lineToHump(ListProductInfo.VALID),
                            RxUtil.StringUtil.lineToHump("STATUS"),
                            RxUtil.StringUtil.lineToHump(ListProductInfo.AD_WORD.toLowerCase()),
                    RxUtil.StringUtil.lineToHump(ListProductInfo.COMPANY_BID.toLowerCase())));
        }

        return resultList;
    }
    public Object listItemInfos(ListSearchVo appLoginVo) throws IllegalAccessException, InstantiationException {

        RxUtil.CheckUtil.check(appLoginVo.getCode(), RESULT_CODE.MESSAGE,"清单编码为空");

        ListItemInfo condition = (ListItemInfo) RxBaseData.create(ListItemInfo.class, HANDLER_TYPE.SINGLE_LIST);

        condition.setStatus(RX_STATUS.NORMAL.getCode());
        condition.getHandlerController().onlyDefault();
        condition.setListCode(appLoginVo.getCode());


        Object object =  standardService.searchList(condition);

        List<ListItemInfo> resultList =  RxUtil.result(object);
        for (ListItemInfo uuaUserInfo : resultList) {
            uuaUserInfo.appendFilter(
                    Arrays.asList(
                            RxUtil.StringUtil.lineToHump(ListProductInfo.UPDATE_DATE),
                            RxUtil.StringUtil.lineToHump(ListProductInfo.VER),
                            RxUtil.StringUtil.lineToHump(ListProductInfo.VALID),
                            RxUtil.StringUtil.lineToHump("STATUS")));
        }

        return resultList;
    }

    public Object listImagePage(ListSearchVo appLoginVo) throws IllegalAccessException, InstantiationException {
        RxUtil.CheckUtil.check(appLoginVo.getListCode(), RESULT_CODE.MESSAGE,"清单编码为空");



        ListItemInfo listItemInfo = (ListItemInfo) ListItemInfo.create(ListItemInfo.class,HANDLER_TYPE.SINGLE_PAGE);
        listItemInfo.setListCode(appLoginVo.getListCode());
        listItemInfo.setTitle(appLoginVo.getTitle());
        listItemInfo.setPageNum(appLoginVo.getPageNum());
        listItemInfo.setPageSize(appLoginVo.getPageSize());
        listItemInfo.setStatus(RX_STATUS.LIMIT.getCode());
        listItemInfo.getHandlerController().onlyDefault();

        Object object =  standardService.searchPage(listItemInfo);

        return object;
    }

    @Transactional
    public Object addListByModel(@RequestBody ListAddVo appLoginVo) throws IllegalAccessException, InstantiationException {

        RxUtil.CheckUtil.check(appLoginVo.getListCode(), RESULT_CODE.MESSAGE,"清单编码为空");
        RxUtil.CheckUtil.check(appLoginVo.getToken(), RESULT_CODE.MESSAGE,"未登录");
        // 判断是否登录。TODO:以后换分布式缓存
        ListLoginVo appLogin = (ListLoginVo)cacheService.getData(appLoginVo.getToken());
        if(EmptyChecker.isEmpty(appLogin)){
            RxUtil.CheckUtil.throwOut(RESULT_CODE.LOGIN_ERR,"未登录");
        }


        ListMainUser listMainUser = (ListMainUser)ListMainUser.create(ListMainUser.class,HANDLER_TYPE.SINGLE_INSERT);
        listMainUser.getHandlerController().onlyDefault();
        RxUtil.copyProperties(appLoginVo,listMainUser);
        listMainUser.setUserBid(appLogin.getBid());
        listMainUser.setStatus(RX_STATUS.NORMAL.getCode());
        standardService.insert(listMainUser);


        ListItemInfo listItemInfo = (ListItemInfo) ListItemInfo.create(ListItemInfo.class,HANDLER_TYPE.SINGLE_LIST);
        listItemInfo.setListCode(appLoginVo.getListCode());
        listItemInfo.setStatus(RX_STATUS.NORMAL.getCode());
        listItemInfo.getHandlerController().onlyDefault();

        Object object =  standardService.searchList(listItemInfo);

        List<ListItemInfo> itemList =  RxUtil.result(object);

        List<RxBaseData> addList = new ArrayList<>();



        if(EmptyChecker.notEmpty(itemList)){
            for (ListItemInfo itemInfo : itemList) {
                if(EmptyChecker.notEmpty(appLoginVo.getBidList())) {
                   if(appLoginVo.getBidList().contains(itemInfo.getBid())){
                       continue;
                   }
                }

                itemInfo.setBid(null);
                ListItemUser listItemUser = new ListItemUser();
                RxUtil.copyProperties(itemInfo,listItemUser);
                listItemUser.setMainBid(listMainUser.getBid());
                listItemUser.setStatus(RX_STATUS.NORMAL.getCode());
                listItemUser.setFinish("0");
                addList.add(listItemUser);
            }
        }

        if(EmptyChecker.notEmpty(appLoginVo.getItemList())){
            for (ListItemUser listItemUser : appLoginVo.getItemList()) {
                listItemUser.setMainBid(listMainUser.getBid());
                listItemUser.setStatus(RX_STATUS.NORMAL.getCode());
                listItemUser.setFinish("0");
                addList.add(listItemUser);
            }
        }

        if(EmptyChecker.isEmpty(addList)){
             return Integer.valueOf(1);
        }

        ListItemUser addCond = (ListItemUser)ListItemUser.create(ListItemUser.class,HANDLER_TYPE.SINGLE_BATCH_INSERT);
        addCond.getHandlerController().onlyDefault();
        addCond.setDataList(addList);



        return  standardService.batchInsert(addCond);
    }

    public Object myListPage(ListAddVo appLoginVo) throws IllegalAccessException, InstantiationException {
        RxUtil.CheckUtil.check(appLoginVo.getToken(), RESULT_CODE.MESSAGE,"未登录");
        // 判断是否登录。TODO:以后换分布式缓存
        ListLoginVo appLogin = (ListLoginVo)cacheService.getData(appLoginVo.getToken());
        if(EmptyChecker.isEmpty(appLogin)){
            RxUtil.CheckUtil.throwOut(RESULT_CODE.LOGIN_ERR,"未登录");
        }

        ListMainUser listMainUser = (ListMainUser) ListMainUser.create(ListMainUser.class,HANDLER_TYPE.SINGLE_PAGE);

        listMainUser.getHandlerController().onlyDefault();
        listMainUser.setUserBid(appLogin.getBid());
        listMainUser.setPageNum(appLoginVo.getPageNum()==null?1:appLoginVo.getPageNum());
        listMainUser.setPageSize(appLoginVo.getPageSize()==null?10:appLoginVo.getPageSize());

        RxUtil.SQL.desc(listMainUser,"id");
        return RxUtil.result(standardService.searchPage(listMainUser));

    }

    private String getGroupBidByEDate(ListAddVo appLoginVo,ListLoginVo appLogin){
        String groupBid="";
        try{
            groupBid= AESUtil.decrypt( appLoginVo.getEncryptedData(), appLogin.getSessionKey(), appLoginVo.getIv());
        }catch (Exception e){

        }

        if(EmptyChecker.isEmpty(groupBid)){
            // 重新获取getSessionKey

            RxUtil.CheckUtil.check(appLoginVo.getCode(), RESULT_CODE.MESSAGE,"获取CODE");


            WxMaService wxMaService = ((WxMaService) wxConfiguration.wxService(wxConfiguration.wxMaConfig()));
            try {
                WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(appLoginVo.getCode());
                appLogin.setSessionKey(session.getSessionKey());
                cacheService.putData(appLogin.getToken(),appLogin);
            } catch (WxErrorException e) {
                log.info("获取SESSION_KEY 失败");
                RxUtil.CheckUtil.check(appLoginVo.getCode(), RESULT_CODE.MESSAGE,"重新获取CODE");
            }
            try{
                groupBid= AESUtil.decrypt( appLoginVo.getEncryptedData(), appLogin.getSessionKey(), appLoginVo.getIv());
            }catch (Exception e){

            }
        }

        if(EmptyChecker.isEmpty(groupBid)){
            // 解码失败
            log.info("解码失败，获取不到群ID");
            return "";
        }

        try {
            OpenGId openGId= JSON.parseObject(groupBid, OpenGId.class);

            return openGId.getOpenGId();
        }catch (Exception e){

        }
        return "";

    }

    private boolean hasAuthor(ListAddVo appLoginVo,ListLoginVo appLogin){

        String groupBid="";

        if("1044".equalsIgnoreCase(appLoginVo.getScene())){
            groupBid = getGroupBidByEDate(appLoginVo,appLogin);
        }else if("1007".equalsIgnoreCase(appLoginVo.getScene())){
            groupBid = appLogin.getBid();
        }
        if(EmptyChecker.isEmpty(groupBid)){
            // 解码失败
            log.info("解码失败，获取不到群ID");
            return false;
        }

        try {
            // 是不是有权限
            ListAuthorityUser listAuthorityUser = (ListAuthorityUser)RxBaseData.create(ListAuthorityUser.class,HANDLER_TYPE.SINGLE_LIST);

            listAuthorityUser.getHandlerController().onlyDefault();
            listAuthorityUser.setScene(appLoginVo.getScene());
            listAuthorityUser.setListBid(appLoginVo.getBid());
            listAuthorityUser.setGroupBid(groupBid);
            listAuthorityUser.setStatus(RX_STATUS.NORMAL.getCode());

            Object object = standardService.searchList(listAuthorityUser);
            List<ListAuthorityUser> list = RxUtil.result(object);
            if(EmptyChecker.notEmpty(list)){
                // 有权限
                return true;
            }

            // 是不是分享者打开。
            ListMainUser listMainUser = (ListMainUser) ListMainUser.create(ListMainUser.class,HANDLER_TYPE.SINGLE_DETAIL);

            listMainUser.getHandlerController().onlyDefault();
            listMainUser.setBid(appLoginVo.getBid());

            listMainUser = (ListMainUser)standardService.detail(listMainUser);

            if(listMainUser.getUserBid().equalsIgnoreCase(appLogin.getBid())){
                // 插入权限
                if("1044".equalsIgnoreCase(appLoginVo.getScene())){
                    listAuthorityUser.resetHandlerType(HANDLER_TYPE.SINGLE_INSERT);
                    listAuthorityUser.getHandlerController().onlyDefault();

                    standardService.insert(listAuthorityUser);
                }

                return true;
            }

            if("1007".equalsIgnoreCase(appLoginVo.getScene())){
                // 查询看看是否有10条 没有10条就添加
                // 第一条就自动获取查看权限

                listAuthorityUser.resetHandlerType(HANDLER_TYPE.SINGLE_LIST);
                listAuthorityUser.getHandlerController().onlyDefault();
                listAuthorityUser.setStatus(null);
                listAuthorityUser.setGroupBid(null);

                Object objectS = standardService.searchList(listAuthorityUser);
                List<ListAuthorityUser> listS = RxUtil.result(objectS);
                if(EmptyChecker.notEmpty(listS)){
                    final String groupBidFinal  = groupBid;
                    List<ListAuthorityUser> groupList = listS.stream().filter(e->groupBidFinal.equalsIgnoreCase(e.getGroupBid())).collect(Collectors.toList());
                    if(listS.size()<10&&groupList.size()<=0){
                        listAuthorityUser.resetHandlerType(HANDLER_TYPE.SINGLE_INSERT);
                        listAuthorityUser.getHandlerController().onlyDefault();
                        listAuthorityUser.setStatus(RX_STATUS.FORBIDDEN.getCode());
                        listAuthorityUser.setNickName(appLogin.getNickName());
                        listAuthorityUser.setGroupBid(groupBid);
                        standardService.insert(listAuthorityUser);
                    }
                    return false;
                }else {
                    listAuthorityUser.resetHandlerType(HANDLER_TYPE.SINGLE_INSERT);
                    listAuthorityUser.getHandlerController().onlyDefault();
                    listAuthorityUser.setStatus(RX_STATUS.NORMAL.getCode());
                    listAuthorityUser.setNickName(appLogin.getNickName());
                    listAuthorityUser.setGroupBid(groupBid);
                    standardService.insert(listAuthorityUser);
                    return true;
                }

            }

        } catch (IllegalAccessException | InstantiationException e) {
            log.info("查询失败");
            return false;
        }


        return false;
    }

    public Object myListDetail(ListAddVo appLoginVo) throws IllegalAccessException, InstantiationException {
        RxUtil.CheckUtil.check(appLoginVo.getToken(), RESULT_CODE.MESSAGE,"未登录");
        RxUtil.CheckUtil.check(appLoginVo.getBid(), RESULT_CODE.MESSAGE,"未登录");

        // 判断是否登录。TODO:以后换分布式缓存
        ListLoginVo appLogin = (ListLoginVo)cacheService.getData(appLoginVo.getToken());
        if(EmptyChecker.isEmpty(appLogin)){
            RxUtil.CheckUtil.throwOut(RESULT_CODE.MESSAGE,"未登录");
        }

        if(EmptyChecker.notEmpty(appLoginVo.getScene())){
            if(!hasAuthor(appLoginVo,appLogin)){
                RxUtil.CheckUtil.throwOut(RESULT_CODE.MESSAGE,"无权查看");
                return "";
            }
        }


        ListItemUser listMainUser = (ListItemUser) ListItemUser.create(ListItemUser.class,HANDLER_TYPE.SINGLE_LIST);

        listMainUser.getHandlerController().onlyDefault();
        listMainUser.setMainBid(appLoginVo.getBid());
        return standardService.searchList(listMainUser);

    }

    /**
     * 更改清单
     * @param appLoginVo
     * @return
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    @Transactional
    public Object doList(@RequestBody ListAddVo appLoginVo) throws IllegalAccessException, InstantiationException {

        RxUtil.CheckUtil.check(appLoginVo.getBid(), RESULT_CODE.MESSAGE,"清单标志为空");
        RxUtil.CheckUtil.check(appLoginVo.getItemList(), RESULT_CODE.MESSAGE,"没有需要更改的信息");
        RxUtil.CheckUtil.check(appLoginVo.getToken(), RESULT_CODE.MESSAGE,"未登录");
        // 判断是否登录。TODO:以后换分布式缓存
        ListLoginVo appLogin = (ListLoginVo)cacheService.getData(appLoginVo.getToken());
        if(EmptyChecker.isEmpty(appLogin)){
            RxUtil.CheckUtil.throwOut(RESULT_CODE.LOGIN_ERR,"未登录");
        }


        ListMainUser listMainUser = (ListMainUser)ListMainUser.create(ListMainUser.class,HANDLER_TYPE.SINGLE_INSERT);
        listMainUser.getHandlerController().onlyDefault();
        listMainUser.setBid(appLoginVo.getBid());
        listMainUser = (ListMainUser) standardService.detail(listMainUser);


        ListItemUser listItemInfo = (ListItemUser) ListItemUser.create(ListItemUser.class,HANDLER_TYPE.SINGLE_BATCH_SAVE);

        listItemInfo.getHandlerController().onlyDefault();

        List<RxBaseData> rxBaseDataList = new ArrayList<>();

        for (ListItemUser listItemUser : appLoginVo.getItemList()) {

            if(EmptyChecker.isEmpty(listItemUser.getBid())){
                listItemUser.setMainBid(listMainUser.getBid());
                listItemUser.setStatus(RX_STATUS.NORMAL.getCode());
                listItemUser.setFinish(listItemUser.getFinish()==null?"0":listItemUser.getFinish());
            }

            rxBaseDataList.add(listItemUser);
        }

        listItemInfo.setDataList(rxBaseDataList);

        // 批量更新
        Object object =  standardService.batchSave(listItemInfo);

        ListItemUser listStatis = (ListItemUser) ListItemUser.create(ListItemUser.class,HANDLER_TYPE.SINGLE_STATIS);


        listStatis.getHandlerController().onlyDefault();
        // 统计
        RxUtil.SQL.sum(listStatis,"cost");
        listStatis.setType("normal");
        listStatis.setMainBid(listMainUser.getBid());

        List<ListItemUser> listStatisList =  (List<ListItemUser> )standardService.statis(listStatis);
        RxUtil.CheckUtil.check(listStatisList, RESULT_CODE.MESSAGE,"统计失败");
        BigDecimal cost = BigDecimal.ZERO;
        if(EmptyChecker.notEmpty(listStatisList.get(0))){
            cost = listStatisList.get(0).getCost();
        }
        // 更新总费用。
        listMainUser.setCost(cost);
        listMainUser.resetHandlerType(HANDLER_TYPE.SINGLE_UPDATE);
        standardService.update(listMainUser);
        return  cost;
    }
    @Transactional
    public Object deleteList(@RequestBody ListAddVo appLoginVo) throws IllegalAccessException, InstantiationException {

        RxUtil.CheckUtil.check(appLoginVo.getItemList(), RESULT_CODE.MESSAGE,"没有需要更改的信息");
        RxUtil.CheckUtil.check(appLoginVo.getToken(), RESULT_CODE.MESSAGE,"未登录");

        // 判断是否登录。TODO:以后换分布式缓存
        ListLoginVo appLogin = (ListLoginVo)cacheService.getData(appLoginVo.getToken());
        if(EmptyChecker.isEmpty(appLogin)){
            RxUtil.CheckUtil.throwOut(RESULT_CODE.LOGIN_ERR,"未登录");
        }


        ListMainUser listItemInfo = (ListMainUser) ListMainUser.create(ListMainUser.class,HANDLER_TYPE.SINGLE_BATCH_SAVE);

        listItemInfo.getHandlerController().onlyDefault();

        List<RxBaseData> rxBaseDataList = new ArrayList<>();

        for (ListItemUser listItemUser : appLoginVo.getItemList()) {

            rxBaseDataList.add(listItemUser);
        }

        listItemInfo.setDataList(rxBaseDataList);

        // 批量更新


        return standardService.batchSave(listItemInfo);
    }

    public Object listAuthPage(@RequestBody ListSearchVo appLoginVo) throws IllegalAccessException, InstantiationException {
        RxUtil.CheckUtil.check(appLoginVo.getToken(), RESULT_CODE.MESSAGE,"未登录");
        RxUtil.CheckUtil.check(appLoginVo.getListBid(), RESULT_CODE.MESSAGE,"没有清单BID");

        // 判断是否登录。TODO:以后换分布式缓存
        ListLoginVo appLogin = (ListLoginVo)cacheService.getData(appLoginVo.getToken());
        if(EmptyChecker.isEmpty(appLogin)){
            RxUtil.CheckUtil.throwOut(RESULT_CODE.LOGIN_ERR,"未登录");
        }

        ListAuthorityUser listAuthorityUser =(ListAuthorityUser)ListAuthorityUser.create(ListAuthorityUser.class,HANDLER_TYPE.SINGLE_LIST);
        listAuthorityUser.getHandlerController().onlyDefault();
        listAuthorityUser.setListBid(appLoginVo.getListBid());
        listAuthorityUser.setScene("1007");


        return standardService.searchList(listAuthorityUser);
    }

    @Transactional
    public Object doListAuth(@RequestBody ListAddVo appLoginVo) throws IllegalAccessException, InstantiationException {
        RxUtil.CheckUtil.check(appLoginVo.getToken(), RESULT_CODE.MESSAGE,"未登录");
        RxUtil.CheckUtil.check(appLoginVo.getAuthList(), RESULT_CODE.MESSAGE,"没有更改");

        // 判断是否登录。TODO:以后换分布式缓存
        ListLoginVo appLogin = (ListLoginVo)cacheService.getData(appLoginVo.getToken());
        if(EmptyChecker.isEmpty(appLogin)){
            RxUtil.CheckUtil.throwOut(RESULT_CODE.LOGIN_ERR,"未登录");
        }

        ListAuthorityUser listAuthorityUser =(ListAuthorityUser)RxBaseData.create(ListAuthorityUser.class,HANDLER_TYPE.SINGLE_BATCH_SAVE);
        listAuthorityUser.getHandlerController().onlyDefault();

        List<RxBaseData> resultList = new ArrayList<>();
        for (ListAuthorityUser authorityUser : appLoginVo.getAuthList()) {
            resultList.add(authorityUser);
        }
        listAuthorityUser.setDataList(resultList);

        return standardService.batchSave(listAuthorityUser);
    }

    private BigDecimal getTicketAmount(String bid){

        ListCompanyInfo listCompanyInfo = (ListCompanyInfo)cacheService.getCompanyData(bid);
        if(EmptyChecker.notEmpty(listCompanyInfo)){
            return (BigDecimal)RxUtil.ofNull(listCompanyInfo.getTicketAmount(),new BigDecimal(100));
        }
        listCompanyInfo = listCompanyInfoMapper.selectTicketAmount(bid);
        if(EmptyChecker.isEmpty(listCompanyInfo)){
            return new BigDecimal(100);
        }else {
            BigDecimal ticketAmount = (BigDecimal)RxUtil.ofNull(listCompanyInfo.getTicketAmount(),new BigDecimal(100));
            cacheService.putCompanyData(bid,ticketAmount);
            return ticketAmount;
        }

    }

    @Transactional
    public Object doBless(@RequestBody ListAddBlessVo appLoginVo) throws IllegalAccessException, InstantiationException {
        RxUtil.CheckUtil.check(appLoginVo.getToken(), RESULT_CODE.MESSAGE,"未登录");
        RxUtil.CheckUtil.check(appLoginVo.getBlessInfo(), RESULT_CODE.MESSAGE,"没有更改");
        RxUtil.CheckUtil.check(appLoginVo.getBlessInfo().getBless(), RESULT_CODE.MESSAGE,"没有祝福");
        RxUtil.CheckUtil.check(appLoginVo.getBlessInfo().getMeBid(), RESULT_CODE.MESSAGE,"没有祝福对象");

        // 判断是否登录。TODO:以后换分布式缓存
        ListLoginVo appLogin = (ListLoginVo)cacheService.getData(appLoginVo.getToken());
        if(EmptyChecker.isEmpty(appLogin)){
            RxUtil.CheckUtil.throwOut(RESULT_CODE.LOGIN_ERR,"未登录");
        }

        ListBlessInfo listBlessInfo =(ListBlessInfo)RxBaseData.create(ListBlessInfo.class,HANDLER_TYPE.SINGLE_LIST);
        listBlessInfo.getHandlerController().onlyDefault();

        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");//定义新的日期格式
        String dateString = formatter.format(new Date());
        listBlessInfo.setMeBid(appLoginVo.getBlessInfo().getMeBid());
        listBlessInfo.setYouBid(appLogin.getBid());
        listBlessInfo.setCompanyBid(appLoginVo.getBlessInfo().getCompanyBid());
        listBlessInfo.setBlessDate(dateString);

        Object o = standardService.searchList(listBlessInfo);
        List<ListBlessInfo> list = RxUtil.result(o);
        RxUtil.CheckUtil.condition(EmptyChecker.notEmpty(list), RESULT_CODE.MESSAGE,"今天已经祝福！");


        listBlessInfo.setBless(appLoginVo.getBlessInfo().getBless());
        listBlessInfo.setYouName(appLogin.getNickName());
        listBlessInfo.setMeName(appLoginVo.getBlessInfo().getMeName());
        listBlessInfo.setCompanyBid(appLoginVo.getBlessInfo().getCompanyBid());
        listBlessInfo.setName(appLoginVo.getBlessInfo().getName());
        listBlessInfo.setStatus(RX_STATUS.NORMAL.getCode());

        listBlessInfo.resetHandlerType(HANDLER_TYPE.SINGLE_INSERT);

        standardService.insert(listBlessInfo);


        ListBlessInfo search =(ListBlessInfo)RxBaseData.create(ListBlessInfo.class,HANDLER_TYPE.SINGLE_LIST);
        search.getHandlerController().onlyDefault();
        search.setMeBid(appLoginVo.getBlessInfo().getMeBid());
        search.setStatus(RX_STATUS.NORMAL.getCode());

        Object osearch = standardService.searchList(search);
        List<ListBlessInfo> toMeBlessList = RxUtil.result(osearch);

        Map<String,List<ListBlessInfo>> compMap = toMeBlessList.stream().collect(Collectors.groupingBy(e->e.getCompanyBid()));

        // 如果考虑并发。放入阻塞队列
        List<RxBaseData> updateList = new ArrayList<>();
        List<RxBaseData> insertList = new ArrayList<>();
        for (Map.Entry<String, List<ListBlessInfo>> stringListEntry : compMap.entrySet()) {
            Map<String,List<ListBlessInfo>> blessMap =  stringListEntry.getValue().stream().collect(Collectors.groupingBy(e->e.getBless()));
            if(blessMap.entrySet().size() >= 5){
                for (Map.Entry<String, List<ListBlessInfo>> blessEntry : blessMap.entrySet()) {
                    ListBlessInfo udp = blessEntry.getValue().get(0);
                    udp.setStatus(RX_STATUS.FROZEN.getCode());
                    // 将5个祝福合成一张券
                    updateList.add(udp);

                }
                ListTicketInfo listTicketInfo = new ListTicketInfo();
                if(stringListEntry.getKey().equals(RxBaseConstant.BID_DEFAULT)){
                    //普通
                    listTicketInfo.setAmount(new BigDecimal(50));
                }else{
                    listTicketInfo.setAmount(getTicketAmount(stringListEntry.getKey()));
                }
                listTicketInfo.setName(stringListEntry.getValue().get(0).getName());
                listTicketInfo.setCompanyBid(stringListEntry.getKey());
                listTicketInfo.setMeBid(appLoginVo.getBlessInfo().getMeBid());
                listTicketInfo.setNickName(appLoginVo.getBlessInfo().getMeName());
                listTicketInfo.setStatus(RX_STATUS.NORMAL.getCode());
                listTicketInfo.setExpiryDate(RxUtil.RxDate.afterDayString(30,RxBaseConstant.DATE_FORMAT_DATEONLY));
                insertList.add(listTicketInfo);
            }
        }

        if(EmptyChecker.notEmpty(updateList)){
            ListBlessInfo batch =(ListBlessInfo)RxBaseData.create(ListBlessInfo.class,HANDLER_TYPE.SINGLE_BATCH_UPDATE);
            batch.getHandlerController().onlyDefault();
            batch.setDataList(updateList);
            standardService.batchUpdate(batch);

        }

        if(EmptyChecker.notEmpty(insertList)){
            ListTicketInfo insert =(ListTicketInfo)RxBaseData.create(ListTicketInfo.class,HANDLER_TYPE.SINGLE_BATCH_INSERT);
            insert.getHandlerController().onlyDefault();
            insert.setDataList(insertList);
            standardService.batchInsert(insert);
        }



        // 计算收集的祝福。是否可以变成券。

        return Integer.valueOf(0);
    }

    private final String YOU = "01";
    private final String  ME= "02";
    private final String QUAN = "03";
    public Object listBlessPage(@RequestBody ListAddBlessVo appLoginVo) throws IllegalAccessException, InstantiationException {

        RxUtil.CheckUtil.check(appLoginVo.getToken(), RESULT_CODE.MESSAGE,"未登录");
        RxUtil.CheckUtil.check(appLoginVo.getType(), RESULT_CODE.MESSAGE,"输入错误");

        ListLoginVo appLogin = (ListLoginVo)cacheService.getData(appLoginVo.getToken());
        if(EmptyChecker.isEmpty(appLogin)){
            RxUtil.CheckUtil.throwOut(RESULT_CODE.LOGIN_ERR,"未登录");
        }




        if (QUAN.equalsIgnoreCase(appLoginVo.getType())){
            ListTicketInfo listTicketInfo = (ListTicketInfo)ListTicketInfo.create(ListTicketInfo.class,HANDLER_TYPE.SINGLE_PAGE);
            listTicketInfo.getHandlerController().onlyDefault();
            listTicketInfo.setPageNum(appLoginVo.getPageNum());
            listTicketInfo.setPageSize(appLoginVo.getPageSize());
            listTicketInfo.setMeBid(appLogin.getBid());
            RxUtil.SQL.desc(listTicketInfo,"id");
            return RxUtil.result(standardService.searchPage(listTicketInfo));
        }

        ListBlessInfo listBlessInfo = (ListBlessInfo)ListBlessInfo.create(ListBlessInfo.class,HANDLER_TYPE.SINGLE_PAGE);
        listBlessInfo.getHandlerController().onlyDefault();
        listBlessInfo.setPageNum(appLoginVo.getPageNum());
        listBlessInfo.setPageSize(appLoginVo.getPageSize());

        RxUtil.SQL.desc(listBlessInfo,"id");

        if (YOU.equalsIgnoreCase(appLoginVo.getType())){
            listBlessInfo.setYouBid(appLogin.getBid());
            return RxUtil.result(standardService.searchPage(listBlessInfo));
        }else if (ME.equalsIgnoreCase(appLoginVo.getType())){
            listBlessInfo.setMeBid(appLogin.getBid());
            return RxUtil.result(standardService.searchPage(listBlessInfo));
        }


        return Integer.valueOf(0);
    }

    public Object preTicketPage(@RequestBody ListAddBlessVo appLoginVo) throws IllegalAccessException, InstantiationException {

        RxUtil.CheckUtil.check(appLoginVo.getToken(), RESULT_CODE.MESSAGE,"未登录");

        ListLoginVo appLogin = (ListLoginVo)cacheService.getData(appLoginVo.getToken());
        if(EmptyChecker.isEmpty(appLogin)){
            RxUtil.CheckUtil.throwOut(RESULT_CODE.LOGIN_ERR,"未登录");
        }


        ListBlessInfo listBlessInfo = (ListBlessInfo)ListBlessInfo.create(ListBlessInfo.class,HANDLER_TYPE.SINGLE_PAGE);
        listBlessInfo.getHandlerController().onlyDefault();
        listBlessInfo.setPageNum(appLoginVo.getPageNum());
        listBlessInfo.setPageSize(appLoginVo.getPageSize());
        listBlessInfo.setMeBid(appLogin.getBid());
        listBlessInfo.setStatus(RX_STATUS.NORMAL.getCode());
        RxUtil.SQL.groupBy(listBlessInfo,"companyBid");
        RxUtil.SQL.desc(listBlessInfo,"id");

        List<ListBlessInfo> listGroup = RxUtil.result(standardService.searchPage(listBlessInfo));
        if(EmptyChecker.isEmpty(listGroup)){
            return listGroup;
        }

        listBlessInfo.resetHandlerType(HANDLER_TYPE.SINGLE_LIST);
        listBlessInfo.setCondition(null);
        listBlessInfo.getHandlerController().onlyDefault();
        List<String> collectBid = listGroup.stream().map(e -> e.getCompanyBid()).collect(Collectors.toList());
        RxUtil.SQL.desc(listBlessInfo,"id");
        RxUtil.SQL.condition(listBlessInfo).put("inCompanyBid",collectBid);

        List<ListBlessInfo> groupList = RxUtil.result(standardService.searchList(listBlessInfo));

        Map<String,List<ListBlessInfo>> compMap = groupList.stream().collect(Collectors.groupingBy(e->e.getCompanyBid()));

        List<CompanyBlessStatistics> list = new ArrayList<>();
        for (Map.Entry<String, List<ListBlessInfo>> stringListEntry : compMap.entrySet()) {
            CompanyBlessStatistics companyBlessStatistics = new CompanyBlessStatistics();
            companyBlessStatistics.setName(stringListEntry.getValue().get(0).getName());
            List<BlessStatistics> blessStatisticsList = new ArrayList<BlessStatistics>();
            companyBlessStatistics.setBless( blessStatisticsList );
            Map<String, List<ListBlessInfo>> blessMap = stringListEntry.getValue().stream().collect(Collectors.groupingBy(e -> e.getBless()));
            for (Map.Entry<String, List<ListBlessInfo>> blessMapEntry : blessMap.entrySet()) {
                BlessStatistics blessStatistics = new BlessStatistics();
                blessStatistics.setBless(blessMapEntry.getKey());
                blessStatistics.setCount(blessMapEntry.getValue().size());
                blessStatisticsList.add(blessStatistics);
            }
            list.add(companyBlessStatistics);
        }

        return list;
    }

    @Transactional
    public Object doTicket(@RequestBody ListAddBlessVo appLoginVo) throws IllegalAccessException, InstantiationException {
        RxUtil.CheckUtil.check(appLoginVo.getToken(), RESULT_CODE.MESSAGE, "未登录");
        RxUtil.CheckUtil.check(appLoginVo.getBid(), RESULT_CODE.MESSAGE, "没有券");
        RxUtil.CheckUtil.check(appLoginVo.getVer(), RESULT_CODE.MESSAGE, "没有版本号");

        // 判断是否登录。TODO:以后换分布式缓存
        ListLoginVo appLogin = (ListLoginVo) cacheService.getData(appLoginVo.getToken());
        if (EmptyChecker.isEmpty(appLogin)) {
            RxUtil.CheckUtil.throwOut(RESULT_CODE.LOGIN_ERR, "未登录");
        }

        ListTicketInfo listTicketInfo = (ListTicketInfo)ListTicketInfo.create(ListTicketInfo.class,HANDLER_TYPE.SINGLE_UPDATE);
        listTicketInfo.setBid(appLoginVo.getBid());
        listTicketInfo.setVer(appLoginVo.getVer());
        listTicketInfo.setStatus(RX_STATUS.FROZEN.getCode());

        return standardService.update(listTicketInfo);
    }

    public Object companyTitle(ListCompanyTitle param) throws IllegalAccessException, InstantiationException {
        RxUtil.CheckUtil.check(param.getCompanyBid(), RESULT_CODE.MESSAGE, "没有公司");

        ListCompanyTitle listCompanyTitle = (ListCompanyTitle)ListCompanyTitle.create(ListCompanyTitle.class,HANDLER_TYPE.SINGLE_LIST);
        listCompanyTitle.setCompanyBid(param.getCompanyBid());
        listCompanyTitle.setStatus(RX_STATUS.NORMAL.getCode());

        return standardService.searchList(listCompanyTitle);

    }


    public Object companyQr(@RequestBody DoCommonVo commonVo) throws IllegalAccessException, InstantiationException {

        RxUtil.CheckUtil.check(commonVo.getBid(), RESULT_CODE.MESSAGE, "参数错误");
        RxUtil.CheckUtil.check(commonVo.getName(), RESULT_CODE.MESSAGE, "名称参数错误");
        ListGuardInfo listGuardInfo = (ListGuardInfo) ListGuardInfo.create(ListGuardInfo.class, HANDLER_TYPE.SINGLE_DETAIL);
        listGuardInfo.setAssBid(commonVo.getBid());
        listGuardInfo.setType(COMPANY_QR_TYPE);
        ListGuardInfo result;

        Object obj = standardService.detail(listGuardInfo);
        if (obj instanceof RxResponse || EmptyChecker.isEmpty(obj)) {
            // 新增
            result = new ListGuardInfo();
            result.setStatus(RX_STATUS.NORMAL.getCode());
            result.setType(COMPANY_QR_TYPE);
            result.setAssBid(commonVo.getBid());
            result.setName(commonVo.getName());
            result.setScene(commonVo.getScene());
            createQr(result);
        }else{
            result = (ListGuardInfo) obj;
        }

        RxUtil.CheckUtil.check(!RX_STATUS.NORMAL.getCode().equalsIgnoreCase(result.getStatus()), RESULT_CODE.MESSAGE, "二维码不存在");


        result.appendFilter(Arrays.asList(
                RxUtil.StringUtil.lineToHump(ListGuardInfo.UPDATE_DATE),
                RxUtil.StringUtil.lineToHump(ListGuardInfo.VER),
                RxUtil.StringUtil.lineToHump(ListGuardInfo.VALID),
                RxUtil.StringUtil.lineToHump(ListGuardInfo.BID),
                RxUtil.StringUtil.lineToHump(ListGuardInfo.ASS_BID_),
                RxUtil.StringUtil.lineToHump(ListGuardInfo.NAME),
                RxUtil.StringUtil.lineToHump(ListGuardInfo.SCENE)
        ));
        return result;
    }

    public Object companyByScene(@RequestBody DoCommonVo commonVo) throws IllegalAccessException, InstantiationException {

        RxUtil.CheckUtil.check(commonVo.getScene(), RESULT_CODE.MESSAGE, "参数错误");

        ListGuardInfo listGuardInfo = (ListGuardInfo)ListGuardInfo.create(ListGuardInfo.class,HANDLER_TYPE.SINGLE_LIST);
        listGuardInfo.getHandlerController().onlyDefault();
        listGuardInfo.setScene(commonVo.getScene());
        listGuardInfo.setStatus(RX_STATUS.NORMAL.getCode());
        List<ListGuardInfo> list = RxUtil.result(standardService.searchList(listGuardInfo)) ;
        RxUtil.CheckUtil.check(list, RESULT_CODE.MESSAGE, "二维码已失效");


        ListCompanyInfo companyInfo = (ListCompanyInfo)ListCompanyInfo.create(ListCompanyInfo.class,HANDLER_TYPE.SINGLE_LIST);
        companyInfo.getHandlerController().onlyDefault();
        companyInfo.setBid(list.get(0).getAssBid());
        companyInfo.setStatus(RX_STATUS.NORMAL.getCode());
        List<ListCompanyInfo> listComp = RxUtil.result(standardService.searchList(companyInfo)) ;
        RxUtil.CheckUtil.check(listComp, RESULT_CODE.MESSAGE, "二维码已失效");
        return listComp.get(0);
    }

    public Object accessToken(ListLoginVo appLoginVo) throws IllegalAccessException, InstantiationException {
        RxUtil.CheckUtil.check(appLoginVo.getToken(), RESULT_CODE.MESSAGE, "未登录");

        // 判断是否登录。TODO:以后换分布式缓存
        ListLoginVo appLogin = (ListLoginVo) cacheService.getData(appLoginVo.getToken());
        if (EmptyChecker.isEmpty(appLogin)) {
            RxUtil.CheckUtil.throwOut(RESULT_CODE.LOGIN_ERR, "未登录");
        }
        WxMaService wxMaService = ((WxMaService) wxConfiguration.wxService(wxConfiguration.wxMaConfig()));
        try {
            appLoginVo.setAccessToken(wxMaService.getAccessToken());
            return appLoginVo;
        } catch (WxErrorException e) {
            return appLoginVo;
        }

    }



}
